import re
import subprocess
from utils.ssh import SSH
from pathlib import Path
from .jsonlib import *
from .jsonsearch import *


class Client():
    def cmd(self, cmd):
        """执行命令"""
        ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE, encoding='utf-8')
        return ret.stdout if (ret.returncode == 0) else ret.stderr


class Remote(SSH):
    def __init__(self, host, username, password, port=22) -> None:
        super().__init__(host=host, username=username, password=password, port=port)

    def cp(self, src, dst):
        self.cmd('cp %s %s' % (src, dst))

    def rm(self, dst):
        self.cmd('rm -rf %s/*' & (dst))

    def mv(self, src, dst):
        self.cmd('mkdir -p %s' % (dst))
        self.ll(dst)
        self.cmd('mv -n %s* %s' % (src, dst))

    def ll(self, dir: str):
        rs = self.cmd('ll %s' % (dir))
        return re.findall(r'.*\d+:\d+\s(.*)\r\n', rs)

    def dusb(self, exclude=None):
        command = 'du -sb --exclude %s' % (exclude) if exclude else 'du -sb'
        rs = self.cmd(command)
        rs = re.search(r'\r\n(\d*)\s+', rs)
        return int(rs.group(1))

    def md5sum(self, dir):
        rs = self.cmd('md5sum %s' % (dir))
        return re.findall(r'\w+\s\w+', rs)

    def upload(self, localpath, remotepath):
        self.sftp.put(localpath=localpath, remotepath=remotepath)

    def download(self, localpath, remotepath):
        self.sftp.get(remotepath=remotepath, localpath=localpath)

    def send_pcap(self, network: str = None, pcap: str = None, speed: int = 5000):
        pcap = '%s/*' % (pcap) if (Path(pcap).is_dir()) else pcap
        rs = self.cmd(f'tcpreplay -i {network} -p {speed} -l 1 {pcap}')
        rs = re.search(r'Successful packets:\s+(\d*)', rs)
        return True if (rs and int(rs.group(1)) > 0) else False

    def read_json(self, file: Path = None):
        content = ''
        with self.sftp.open(file, 'r') as f:
            content = f.read()
            try:
                return content.decode(encoding='utf-8', errors='ignore')
            except (UnicodeError, AttributeError):
                return content

    def iterdir(self, folder_path: Path = None):
        for file_path in self.ll(folder_path):
            file_path = file_path.strip().strip('"').strip("'")
            yield Path(folder_path).joinpath(file_path).as_posix()

    def edit_file(self, file: Path = None, content: str = ''):
        self.cmd('cd %s' % (file.parent))
        self.cmd('touch %s' % (file.name))
        self.cmd('echo %s > %s' % (content, file.name))

    def search_values_many(self, fodler_path, key, duplicate_check, accurate: list = []):
        """遍历目录下文件，查找所有文件并合并查找结果"""
        json_obj_list = []
        for file_path in self.iterdir(fodler_path):
            json_obj = json_in_file(
                file_path=file_path, read_file_func=self.read_json, duplicate_check=duplicate_check)
            if (isinstance(json_obj, list)):
                json_obj_list = json_obj_list + json_obj
            elif (isinstance(json_obj, dict)):
                json_obj_list.append(json_obj)
        return search_values(json_obj_list, key, accurate)

    def search_values_single(self, fodler_path, key, duplicate_check, accurate: list = []):
        """遍历目录下文件，若在文件中找到值则直接返回查找结果，否则继续查找至结束"""
        for file_path in self.iterdir(fodler_path):
            json_obj = json_in_file(
                file_path=file_path, read_file_func=self.read_json, duplicate_check=duplicate_check)
            values = search_values(json_obj, key, accurate)
            if (values):
                return values
        return []
